/**
 * 简易 PCM16 播放器
 * - 输入: ArrayBuffer(Int16 PCM), 单声道
 * - 采样率: 默认 22050Hz，可配置
 * - 策略: 为每个分片创建 AudioBufferSourceNode，按时间轴排队播放
 */

export interface PcmPlayerOptions {
  sampleRate?: number // 默认 22050
}

export default class PcmPlayer {
  private ctx: AudioContext
  private sampleRate: number
  private scheduledAt = 0 // 已调度到时间
  private analyser: AnalyserNode

  constructor(opts: PcmPlayerOptions = {}) {
    this.ctx = new (window.AudioContext || (window as any).webkitAudioContext)()
    this.sampleRate = opts.sampleRate ?? 22050
    this.analyser = this.ctx.createAnalyser()
    this.analyser.fftSize = 2048
    // 默认将 analyser 输出到 destination
    this.analyser.connect(this.ctx.destination)
  }

  /** 输入一段 PCM16 分片 */
  feed(buffer: ArrayBuffer) {
    const i16 = new Int16Array(buffer)
    const f32 = new Float32Array(i16.length)
    for (let i = 0; i < i16.length; i++) {
      const s = i16[i] / 0x8000
      f32[i] = Math.max(-1, Math.min(1, s))
    }

    const audioBuffer = this.ctx.createBuffer(1, f32.length, this.sampleRate)
    audioBuffer.getChannelData(0).set(f32)

    const source = this.ctx.createBufferSource()
    source.buffer = audioBuffer
    // 连接到 analyser，再到 destination（构造时已连好）
    source.connect(this.analyser)

    const now = this.ctx.currentTime
    if (this.scheduledAt < now) this.scheduledAt = now
    source.start(this.scheduledAt)
    this.scheduledAt += audioBuffer.duration
  }

  /** 立即停止并清零排队 */
  stop() {
    try { this.ctx.close() } catch {}
    this.ctx = new (window.AudioContext || (window as any).webkitAudioContext)()
    this.scheduledAt = 0
    this.analyser = this.ctx.createAnalyser()
    this.analyser.fftSize = 2048
    this.analyser.connect(this.ctx.destination)
  }

  /** 暴露用于可视化的 analyser 节点 */
  getAnalyser(): AnalyserNode {
    return this.analyser
  }
}


